﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
using HtmlAgilityPack;

namespace TomatoSynchronizer.Store
{
    public class CategoryStore
    {
    	private Site _site;
		private HtmlWeb _client;
		private List<IDictionary> _allCategories;
		JavaScriptSerializer serialiser;
		
        public CategoryStore(Site site,HtmlWeb client)
		{
        	_site = site;
			_client = client;
			serialiser = new JavaScriptSerializer();
			_allCategories = new List<IDictionary>();
		}

        private void SynchroniseCategories()
        {
            GetAllCategories();
            UploadAllCategories();
        }

        public List<IDictionary> GetAllCategories()
        {            
            List<IDictionary> rootCategories = GetCategories(0);

            _allCategories.AddRange(rootCategories);

            foreach (IDictionary category in rootCategories)
            {
                GetSubCategories(category);
            }
            
            return _allCategories;
        }

        private IDictionary GetCategory(string categoryId)
        {
            IDictionary categorie = null;

            HtmlDocument categoryDocument = _client.Load(_site.Url + "/admin/json.php?action=load_category&categories_id=" + categoryId + "&module=categories");            
            
            if (categoryDocument.DocumentNode != null)
            {
                foreach (HtmlNode node in categoryDocument.DocumentNode.SelectNodes("/"))
                {
                    categorie = serialiser.Deserialize<IDictionary>(node.InnerText);
                    if (categorie != null)
                    {                        
                        foreach (string key in categorie.Keys)
                        {
                            if (key == "data")
                            {
                                IDictionary item = (IDictionary)categorie[key];
                                if (item != null)
                                {                                    
                                    Utility.DownloadImage(_site.Url + "/images/categories/" + item["categories_image"].ToString());

                                    return item;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        private void UploadCategory(IDictionary category, string parentId)
        {
            CookieContainer cookies = new CookieContainer();

            NameValueCollection querystring = new NameValueCollection();

            querystring["parent_category_id"] = parentId;
            querystring["categories_url[2]"] = category["categories_url"].ToString();
            querystring["categories_name[2]"] = category["categories_name"].ToString();
            querystring["parentId"] = parentId;
            querystring["sort_order"] = category["sort_order"].ToString();
            querystring["categories_status"] = category["categories_status"].ToString();
            querystring["page_title[2]"] = category["page_title"] != null ? category["page_title"].ToString() : category["categories_name"].ToString();
            querystring["meta_keywords[2]"] = category["meta_keywords"] != null ? category["meta_keywords"].ToString() : "";
            querystring["meta_description[2]"] = category["meta_description"] != null ? category["ratings"].ToString() : "";
            querystring["ratings"] = category["ratings"] != null ? category["ratings"].ToString() : "";
            querystring["module"] = "categories";
            querystring["action"] = "save_category";

            string uploadfile = category["categories_image"].ToString();

            string response = Utility.UploadFileEx(uploadfile, _site.Url + "/admin/json.php", "image", "image/pjpeg",
                         querystring, cookies);

            IDictionary json = serialiser.Deserialize<IDictionary>(response);
            if (json != null)
            {
                foreach (string key in json.Keys)
                {
                    if (key == "categories_id")
                    {
                        category["remoteId"] = json[key].ToString();
                    }
                }
            }

            foreach (IDictionary categorie in _allCategories)
            {
                if (categorie["parent_id"].ToString() == category["categories_id"].ToString())
                {
                    UploadCategory(categorie, category["remoteId"].ToString());
                }
            }
        }

        public void GetSubCategories(IDictionary parentCategory)
        {
            List<IDictionary> subCategories = GetCategories(int.Parse(parentCategory["categories_id"].ToString()));
            _allCategories.AddRange(subCategories);
            foreach (IDictionary category in subCategories)
            {
                GetSubCategories(category);
            }
        }

        private void UploadAllCategories()
        {
//            top categories first
            foreach (IDictionary category in _allCategories)
            {
                if (category["parent_id"].ToString() == "0")
                {
                    UploadCategory(category, "0");
                }
            }
        }

        private List<IDictionary> GetCategories(int parentId)
        {
            List<IDictionary> categories = new List<IDictionary>();

            HtmlDocument rootCategoriesDoc = _client.Load(_site.Url + "/admin/json.php?action=list_categories&categories_id=" + parentId + "&module=categories");

            if (rootCategoriesDoc.DocumentNode != null)
            {
                foreach (HtmlNode node in rootCategoriesDoc.DocumentNode.SelectNodes("/"))
                {
                    try
                    {
                        IDictionary json = serialiser.Deserialize<IDictionary>(node.InnerText);
                        if (json != null)
                        {                            
                            foreach (string key in json.Keys)
                            {
                                if (key == "records")
                                {
                                	object[] list = (object[])json[key];

                                    if (list != null)
                                    {
                                        for (int i = 0; i < list.Length; i++)
                                        {
                                            IDictionary category = (IDictionary)list[i];
                                            if (category != null)
                                            {
                                                IDictionary item = GetCategory(category["categories_id"].ToString());
                                                categories.Add(item);
                                            }
                                        }
                                    }
                                }                                
                            }
                        }
                    }
                    catch (ArgumentException)
                    {                        
                    }
                }
            }

            return categories;
        }
    }
}
